/**
 * JavaScript功能
 * 日期：2019-12-1 19:08:05
 * 作者：Verning Aulence
 */

import { showIntlDateTime } from './utils/format-date-time.js';
import ShortTipsTools from '../plugins/short-tips.js';
import { qe, qes } from './utils/query-elements.js';

// 全局变量
const GLOBAL = {
  author: 'Verning Aulence',
  titleName() {
    return document.querySelector('head > title').textContent;
  },
  getClassification() {
    // 优先：文档页左侧导航的分类（main.doc-page 下的 nav 的类名）
    const docNav = document.querySelector('main.doc-page nav');
    if (docNav) {
      if (docNav.classList.contains('html')) return 'html';
      if (docNav.classList.contains('css')) return 'css';
      if (docNav.classList.contains('javascript')) return 'javascript';
    }

    // 其次：根据 URL 路径片段推断分类
    const segments = location.pathname.toLowerCase().split('/');
    if (segments.includes('html')) return 'html';
    if (segments.includes('css')) return 'css';
    if (segments.includes('javascript')) return 'javascript';

    // 兜底：根据标题文本推断
    const title = (document.querySelector('head > title')?.textContent || '').toLowerCase();
    if (title.includes('html')) return 'html';
    if (title.includes('css')) return 'css';
    if (title.includes('javascript')) return 'javascript';

    return '';
  },

  // 图片查看器
  imageViewer: {
    // 当前查看的图片元素
    currentImg: null,
    // 遮罩层元素
    overlay: null,
    // 放大后的图片容器
    container: null,
    // 放大后的图片元素
    enlargedImg: null,
    // 动画持续时间（毫秒）
    animationDuration: 500,
    // 是否正在动画中
    isAnimating: false
  },

  // 动态锚点导航
  dynamicAnchor: {
    // 当前激活的导航元素
    activeToggle: null,
    // 导航列表元素
    navList: null,
    // 动画持续时间（毫秒）
    animationDuration: 300,
    // 是否正在显示
    isShowing: false
  }
};

// 轻提示插件初始化
const tips = new ShortTipsTools(document.body);
tips.init();

/**
 * 页面加载完成后执行
 */
window.addEventListener('load', () => {
  console.log(`您好，尊敬的程序猿大人！`);
  console.log(`现在的时间是：${showIntlDateTime(new Date())}`);

  // 判断当前所处页面并添加 active 类
  onthePageName(GLOBAL);

  // 设置左侧导航栏当前页面的选中状态
  setLeftNavActive();

  // 初始化图片点击放大功能
  initImageViewer();

  // 初始化动态锚点导航功能
  initDynamicAnchor();

  // 成功提示
  tips.info({
    mesg: `项目作者是：${GLOBAL.author}`,
    duration: 3000,
    masklayer: false,
  });


  // FIXME:（限开发期间使用）是为了方便观察最新编写的文档内容
  setTimeout(() => {
    const lastH2 = qe('.doc-content > p:last-of-type');
    if (lastH2) {
      lastH2.scrollIntoView(true);
    }
  }, 800);

});

/**
 * 判断当前所处页面
 */
function onthePageName(global) {
  const classification = global.getClassification();
  const navList = qes('header nav li');
  if (classification === 'html') {
    qe(navList[0], 'a').classList.add('active');
  }
  else if (classification === 'css') {
    qe(navList[1], 'a').classList.add('active');
  }
  else if (classification === 'javascript') {
    qe(navList[2], 'a').classList.add('active');
  }
}

/**
 * 设置左侧导航的选中状态
 * 规则：匹配当前页面文件名与导航链接的文件名相同的项
 */
function setLeftNavActive() {
  const leftNav = qe('.left-navlist');
  if (!leftNav) return;

  // 当前页面文件名
  const currentName = location.pathname.split('/').pop();

  // 所有导航链接
  const links = qes(leftNav, 'a');
  links.forEach((a) => {
    const hrefName = (a.getAttribute('href') || '').split('/').pop();
    const li = a.parentElement;
    if (!li) return;

    if (hrefName === currentName) {
      li.classList.add('active');
    } else {
      li.classList.remove('active');
    }
  });
}

/**
 * 初始化图片点击放大功能
 * 为 div.img-content 容器内的所有图片添加点击放大功能
 */
function initImageViewer() {
  // 使用事件委托，监听 document 上的点击事件
  document.addEventListener('click', (event) => {
    // 检查点击的元素是否是 div.img-content 内的图片
    const target = event.target;
    if (target.tagName === 'IMG' && isInImgContent(target)) {
      showEnlargedImage(target);
    }
  });
}

/**
 * 检查元素是否在 div.img-content 容器内
 * @param {HTMLElement} element - 要检查的元素
 * @returns {boolean} - 是否在 div.img-content 容器内
 */
function isInImgContent(element) {
  let current = element;
  while (current && current !== document.body) {
    if (current.classList && current.classList.contains('img-content')) {
      return true;
    }
    current = current.parentElement;
  }
  return false;
}

/**
 * 显示放大的图片
 * @param {HTMLImageElement} imgElement - 被点击的图片元素
 */
function showEnlargedImage(imgElement) {
  // 防止重复点击或动画中点击
  if (GLOBAL.imageViewer.isAnimating || GLOBAL.imageViewer.overlay) return;

  GLOBAL.imageViewer.isAnimating = true;
  GLOBAL.imageViewer.currentImg = imgElement;

  // 创建遮罩层
  const overlay = document.createElement('div');
  overlay.className = 'image-viewer-overlay';

  // 创建图片容器
  const container = document.createElement('div');
  container.className = 'image-viewer-container';

  // 创建放大的图片
  const enlargedImg = document.createElement('img');
  enlargedImg.className = 'image-viewer-img';
  enlargedImg.src = imgElement.src;
  enlargedImg.alt = imgElement.alt || '';

  // 组装 DOM
  container.appendChild(enlargedImg);
  overlay.appendChild(container);
  document.body.appendChild(overlay);

  // 存储引用
  GLOBAL.imageViewer.overlay = overlay;
  GLOBAL.imageViewer.container = container;
  GLOBAL.imageViewer.enlargedImg = enlargedImg;

  // 添加点击关闭事件
  overlay.addEventListener('click', (event) => {
    // 点击图片不关闭，点击遮罩层才关闭
    if (event.target === overlay) {
      hideEnlargedImage();
    }
  });

  // 图片本身也可以点击关闭
  enlargedImg.addEventListener('click', hideEnlargedImage);

  // 图片加载完成后调整尺寸并显示
  enlargedImg.onload = () => {
    adjustImageSize(enlargedImg);

    // 触发显示动画
    requestAnimationFrame(() => {
      overlay.classList.add('show');
      container.classList.add('show');

      // 动画结束后重置状态
      setTimeout(() => {
        GLOBAL.imageViewer.isAnimating = false;
      }, GLOBAL.imageViewer.animationDuration);
    });
  };
}

/**
 * 隐藏放大的图片
 */
function hideEnlargedImage() {
  // 防止重复点击或没有显示图片
  if (GLOBAL.imageViewer.isAnimating || !GLOBAL.imageViewer.overlay) return;

  GLOBAL.imageViewer.isAnimating = true;

  const { overlay, container } = GLOBAL.imageViewer;

  // 触发隐藏动画
  overlay.classList.remove('show');
  container.classList.remove('show');

  // 动画结束后移除 DOM
  setTimeout(() => {
    document.body.removeChild(overlay);

    // 重置状态
    GLOBAL.imageViewer.overlay = null;
    GLOBAL.imageViewer.container = null;
    GLOBAL.imageViewer.enlargedImg = null;
    GLOBAL.imageViewer.currentImg = null;
    GLOBAL.imageViewer.isAnimating = false;
  }, GLOBAL.imageViewer.animationDuration);
}

/**
 * 根据图片和窗口尺寸调整图片大小
 * @param {HTMLImageElement} imgElement - 图片元素
 */
function adjustImageSize(imgElement) {
  // 获取图片原始尺寸
  const imgWidth = imgElement.naturalWidth;
  const imgHeight = imgElement.naturalHeight;

  // 获取窗口尺寸（减去一些边距）
  const windowWidth = window.innerWidth * 0.9;
  const windowHeight = window.innerHeight * 0.9;

  // 如果图片尺寸小于窗口尺寸，按原始尺寸显示
  if (imgWidth < windowWidth && imgHeight < windowHeight) {
    imgElement.style.width = `${imgWidth}px`;
    imgElement.style.height = `${imgHeight}px`;
    return;
  }

  // 计算宽高比
  const imgRatio = imgWidth / imgHeight;
  const windowRatio = windowWidth / windowHeight;

  // 根据宽高比决定如何缩放
  if (imgRatio > windowRatio) {
    // 图片更宽，以窗口宽度为基准
    imgElement.style.width = `${windowWidth}px`;
    imgElement.style.height = 'auto';
  } else {
    // 图片更高，以窗口高度为基准
    imgElement.style.width = 'auto';
    imgElement.style.height = `${windowHeight}px`;
  }
}

/**
 * 初始化动态锚点导航功能
 */
function initDynamicAnchor() {
  // 查找所有 aside.toggle-dynamic-anchor 元素
  const toggleElements = qes('aside.toggle-dynamic-anchor');
  if (!toggleElements || toggleElements.length === 0) return;

  // 为每个触发元素添加点击事件
  toggleElements.forEach((toggle) => {
    toggle.addEventListener('click', (event) => {
      event.stopPropagation();
      toggleDynamicAnchorNav(toggle);
    });
  });

  // 点击页面其他区域隐藏导航
  document.addEventListener('click', (event) => {
    if (GLOBAL.dynamicAnchor.isShowing && GLOBAL.dynamicAnchor.navList) {
      const navList = GLOBAL.dynamicAnchor.navList;
      // 如果点击的不是导航列表内的元素，则隐藏导航
      if (!navList.contains(event.target)) {
        hideDynamicAnchorNav();
      }
    }
  });
}

/**
 * 切换动态锚点导航的显示/隐藏
 * @param {HTMLElement} toggleElement - 触发元素
 */
function toggleDynamicAnchorNav(toggleElement) {
  // 如果已经显示，则隐藏
  if (GLOBAL.dynamicAnchor.isShowing && GLOBAL.dynamicAnchor.activeToggle === toggleElement) {
    hideDynamicAnchorNav();
    return;
  }

  // 如果有其他导航正在显示，先隐藏它
  if (GLOBAL.dynamicAnchor.isShowing) {
    hideDynamicAnchorNav();
  }

  // 显示新的导航
  showDynamicAnchorNav(toggleElement);
}

/**
 * 显示动态锚点导航
 * @param {HTMLElement} toggleElement - 触发元素
 */
function showDynamicAnchorNav(toggleElement) {
  // 查找当前页面的所有 h2 标题
  const docContent = qe('.doc-content');
  if (!docContent) return;

  const h2Elements = qes(docContent, 'h2');
  if (!h2Elements || h2Elements.length === 0) {
    tips.warning({
      mesg: '当前页面没有可用的标题',
      duration: 2000,
      masklayer: false,
    });
    return;
  }

  // 过滤规则：保留 section.chapter-exercise 本身的 h2，但排除其内部的子 h2
  const filteredH2Elements = Array.from(h2Elements).filter((h2) => {
    // 检查 h2 的直接父元素是否是 section.chapter-exercise
    const directParent = h2.parentElement;
    if (directParent && directParent.tagName === 'SECTION' && directParent.classList.contains('chapter-exercise')) {
      // 如果 h2 是 section.chapter-exercise 的直接子元素，保留它
      return true;
    }

    // 检查 h2 是否在 section.chapter-exercise 的更深层级内部
    let current = directParent;
    while (current && current !== docContent) {
      if (current.tagName === 'SECTION' && current.classList.contains('chapter-exercise')) {
        return false; // 如果 h2 在 chapter-exercise 的深层内部，过滤掉
      }
      current = current.parentElement;
    }
    return true; // 其他情况保留
  });

  // 如果过滤后没有 h2 了，显示提示
  if (filteredH2Elements.length === 0) {
    tips.warning({
      mesg: '当前页面没有可用的标题',
      duration: 2000,
      masklayer: false,
    });
    return;
  }

  // 创建导航列表
  const navList = document.createElement('ul');
  navList.className = 'dynamic-anchor-list';

  // 为每个 h2 生成导航项（使用过滤后的列表）
  filteredH2Elements.forEach((h2, index) => {
    const li = document.createElement('li');
    const text = h2.textContent.trim();
    li.textContent = text;

    // 检查 h2 的直接父元素是否是 section.chapter-exercise
    const directParent = h2.parentElement;
    if (directParent && directParent.tagName === 'SECTION' && directParent.classList.contains('chapter-exercise')) {
      // 如果是章节练习的主标题，添加 no-counter 类
      li.classList.add('no-counter');
    }

    // 为 h2 添加 id（如果没有的话）
    if (!h2.id) {
      h2.id = `anchor-${index}`;
    }

    // 点击导航项滚动到对应位置
    li.addEventListener('click', (event) => {
      event.stopPropagation();
      scrollToElement(h2);
      // 滚动后隐藏导航
      setTimeout(() => {
        hideDynamicAnchorNav();
      }, 300);
    });

    navList.appendChild(li);
  });

  // 将导航列表插入到 aside 内
  toggleElement.appendChild(navList);

  // 更新全局状态
  GLOBAL.dynamicAnchor.activeToggle = toggleElement;
  GLOBAL.dynamicAnchor.navList = navList;
  GLOBAL.dynamicAnchor.isShowing = true;

  // 触发显示动画
  requestAnimationFrame(() => {
    navList.classList.add('show');
  });
}

/**
 * 隐藏动态锚点导航
 */
function hideDynamicAnchorNav() {
  if (!GLOBAL.dynamicAnchor.navList) return;

  const navList = GLOBAL.dynamicAnchor.navList;

  // 触发隐藏动画
  navList.classList.remove('show');

  // 动画结束后移除 DOM
  setTimeout(() => {
    if (navList.parentElement) {
      navList.parentElement.removeChild(navList);
    }

    // 重置全局状态
    GLOBAL.dynamicAnchor.activeToggle = null;
    GLOBAL.dynamicAnchor.navList = null;
    GLOBAL.dynamicAnchor.isShowing = false;
  }, GLOBAL.dynamicAnchor.animationDuration);
}

/**
 * 平滑滚动到指定元素
 * @param {HTMLElement} element - 目标元素
 */
function scrollToElement(element) {
  if (!element) return;

  // 查找滚动容器（main 标签）
  const scrollContainer = document.querySelector('main');
  if (!scrollContainer) {
    console.warn('未找到 main 滚动容器');
    return;
  }

  // 获取目标元素相对于滚动容器的位置
  const containerRect = scrollContainer.getBoundingClientRect();
  const elementRect = element.getBoundingClientRect();

  // 计算目标滚动位置（相对于容器当前滚动位置）
  // elementRect.top 是相对于视口的位置
  // containerRect.top 是容器相对于视口的位置
  // scrollContainer.scrollTop 是容器当前的滚动位置
  const targetScrollTop = scrollContainer.scrollTop + (elementRect.top - containerRect.top) - 80;

  // 平滑滚动到目标位置
  scrollContainer.scrollTo({
    top: targetScrollTop,
    behavior: 'smooth'
  });
}
